from __future__ import division
import ctypes
from math import sqrt


class Vec3(ctypes.Array):
	"""Simple 3D vector type"""
	
	_length_ = 3
	_type_ = ctypes.c_float

	def __getattr__(self, name):
		return self['xyz'.index(name)]
	
	def __setattr__(self, name, value):
		self['xyz'.index(name)] = value

	def __repr__(self):
		return '%s(%s, %s, %s)' % (self.__class__.__name__, self.x, self.y, self.z)
	
	## Vector math methods to be moved to C ##

	def length((x, y, z)):
		return sqrt(x**2 + y**2 + z**2)
	
	def normalize(self):
		L = self.length()
		if L != 0:
			x, y, z = self
			return self.__class__(x / L, y / L, z / L)
		else:
			return self.__class__(0, 0, 0)

	def __nonempty__((x, y, z)):
		return x != 0 or y !=0 or z != 0
	
	def __lt__((sx, sy, sz), (ox, oy, oz)):
		return (sx**2 + sy**2 + sz**2) < (ox**2 + oy**2 + oz**2)

	def __gt__((sx, sy, sz), (ox, oy, oz)):
		#sx, sy, sz = self
		#ox, oy, oz = other
		return (sx**2 + sy**2 + sz**2) > (ox**2 + oy**2 + oz**2)
	
	def dot(self, (ox, oy, oz)):
		"""Dot product"""
		return self.x*ox + self.y*oy + self.z*oz
	
	def cross(self, (ox, oy, oz)):
		"""Cross product"""
		sx, sy, sz = self
		return self.__class__(sy*oz - sz*oy, sz*ox - sx*oz, sx*oy - sy*ox)

	'''
	def __mul__(self, (ox, oy, oz)):
		sx, sy, sz = self
		return self.__class__(sx*ox, sy*oy, sz*oz)
	
	def __div__(self, (ox, oy, oz)):
		sx, sy, sz = self
		return self.__class__(sx/ox, sy/oy, sz/oz)

	'''

	def __add__(self, (ox, oy, oz)):
		sx, sy, sz = self
		return self.__class__(sx+ox, sy+oy, sz+oz)
	
	def __iadd__(self, (ox, oy, oz)):
		self[0] += ox
		self[1] += oy
		self[2] += oz
		return self

	def __sub__(self, (ox, oy, oz)):
		sx, sy, sz = self
		return self.__class__(sx-ox, sy-oy, sz-oz)

	def __isub__(self, (ox, oy, oz)):
		self[0] -= ox
		self[1] -= oy
		self[2] -= oz
		return self
	
	def __mul__(self, scalar):
		sx, sy, sz = self
		return self.__class__(sx*scalar, sy*scalar, sz*scalar)	

	def __neg__(self):
		x, y, z = self
		return self.__class__(-x, -y, -z)

	def reflect(self, normal):
		sx, sy, sz = self
		nx, ny, nz = normal
		d = self.dot(normal)*2
		return self.__class__(sx - d*nx, sy - d*ny, sz - d*nz)


class Color(ctypes.Array):
	"""Simple rgba color type"""
	_length_ = 4
	_type_ = ctypes.c_float

	def __getattr__(self, name):
		return self['rgba'.index(name)]
	
	def __setattr__(self, name, value):
		self['rgba'.index(name)] = value

	def __repr__(self):
		return '%s(%s, %s, %s, %s)' % (self.__class__.__name__, 
			self.r, self.g, self.b, self.a)


def where_line_intersects_plane(pa, pb, plane_height):
	denominator = pb[2] - pa[2]
	if denominator == 0:
		return None
	t = float(plane_height - pa[2]) / denominator
	return pa + (pb - pa) * t

